package main

import (
	"bytes"
	"fmt"
	"math"
)

type Point struct {
	X, Y float64
}

func Distance(p, q Point) float64 {
	return math.Hypot(q.X - p.X, q.Y - p.Y)
}

func (p Point) Distance(q Point) float64 {
	return math.Hypot(q.X - p.X, q.Y - p.Y)
}

/*
	接收器为指针
 */
func (p *Point)ScaleBy(factor float64)  {
	p.X *= factor
	p.Y *= factor
}

func distance_test() {
	p := Point{1, 2}
	q := Point{4, 6}
	fmt.Printf("function invoke: %.0f\n", Distance(p, q))
	fmt.Printf("Method invoke: %.2f\n", p.Distance(q))
}

type IntSet struct {
	words []uint64
}

func (s *IntSet) Has(x int) bool {
	word, bit := x/64, uint(x%64)
	return  word < len(s.words) && s.words[word]&(1 << bit) != 0
}

func (s *IntSet) Add(x int) {
	word, bit := x/64, uint(x%64)
	for word >= len(s.words){
		s.words = append(s.words, 0)
	}
	s.words[word] |= 1<<bit
}

func (s *IntSet) UnionWith(t *IntSet) {
	for i, tword := range t.words {
		if i < len(s.words){
			s.words[i] |= tword
		}else {
			s.words = append(s.words, tword)
		}
	}
}

func (s *IntSet) String() string {
	var buf bytes.Buffer
	buf.WriteByte('{')
	for i, word := range s.words{
		if word == 0{
			continue
		}
		for j := 0; j < 64; j++ {
			if word&(1<<uint(j)) != 0{
				if buf.Len() > len("{"){
					buf.WriteByte(' ')
				}
				fmt.Fprintf(&buf, "%d", 64*i + j)
			}
		}
	}
	buf.WriteByte('}')
	return buf.String()
}

func main() {
	distance_test()
}
